package com.camtc.camcenter.util;

import cn.hutool.core.collection.CollUtil;
import com.camtc.camcenter.enums.CustomErrorInfo;
import com.camtc.camcenter.exception.CustomException;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * bean Map 切换
 *
 * @author
 * @date
 */
public class BeanUtil {

    private BeanUtil() {
    }

    /**
     * 将 MAP 对象转化成JAVABEAN
     *
     * @param data
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T convertMapBean(Map<String, Object> data, Class<T> t) {
        try {
            T bean = t.newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(t);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            Arrays.stream(propertyDescriptors).forEach(propertyDescriptor -> {
                if (data.containsKey(propertyDescriptor.getName())) {
                    try {
                        propertyDescriptor.getWriteMethod().invoke(bean, data.get(propertyDescriptor.getName()));
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        throw new CustomException(CustomErrorInfo.SYS_ERROR, "转化异常");
                    }
                }
            });
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将 JAVABEAN 转为Map 对象
     *
     * @param t
     * @param item
     * @param <T>
     * @return
     */
    public static <T> Map<String, Object> convertBeanMap(Class<T> t, T item) {
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(t);
            PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor descriptor : descriptors) {
                if (descriptor.getPropertyType().equals(Class.class)) {
                    continue;
                }
                map.put(descriptor.getName(), descriptor.getReadMethod().invoke(item));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 将 List<Map>对象转化为List<JavaBean>
     *
     * @param listMap
     * @param t
     * @param <T>
     * @return
     */
    public static <T> List<T> convertListMapListBean(List<Map<String, Object>> listMap, Class<T> t) {
        List<T> beanList = new ArrayList<>();
        if (CollUtil.isNotEmpty(listMap)) {
            for (Map<String, Object> objectMap : listMap) {
                beanList.add(convertMapBean(objectMap, t));
            }
        }
        return beanList;
    }

    /**
     * 返回BEAN 的属性集合
     *
     * @param <T>
     * @param t
     * @return
     */
    public static <T> Set<String> beanKeys(Class<T> t) {
        Set<String> keys = new LinkedHashSet<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(t);
            Arrays.stream(beanInfo.getPropertyDescriptors()).forEach(propertyDescriptor -> keys.add(propertyDescriptor.getName()));
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        return keys;
    }

}
